package com.cecsmsserve.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cecsmsserve.entity.News;
import com.cecsmsserve.entity.NewsCategory;
import com.cecsmsserve.entity.NewsCategoryRel;
import com.cecsmsserve.mapper.NewsCategoryMapper;
import com.cecsmsserve.mapper.NewsCategoryRelMapper;
import com.cecsmsserve.mapper.NewsMapper;
import com.cecsmsserve.service.NewsService;
import com.cecsmsserve.util.result.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class NewsServiceImpl extends ServiceImpl<NewsMapper, News> implements NewsService {

    @Autowired
    private NewsMapper newsMapper;

    @Autowired
    private NewsCategoryMapper categoryMapper;

    @Autowired
    private NewsCategoryRelMapper categoryRelMapper;

    @Override
    @Transactional
    public CommonResult addNews(News news, List<Integer> categoryIds) {
        // 设置发布时间
        news.setPublishTime(LocalDateTime.now());
        // 设置默认值
        news.setViewCount(0);
        
        // 保存新闻
        boolean saved = save(news);
        if (!saved) {
            return CommonResult.failed("添加新闻失败");
        }
        
        // 保存分类关系
        saveNewsCategoryRels(news.getId(), categoryIds);
        
        return CommonResult.success(news.getId());
    }

    @Override
    @Transactional
    public CommonResult updateNews(News news, List<Integer> categoryIds) {
        // 设置更新时间
        news.setUpdateTime(LocalDateTime.now());
        
        // 更新新闻
        boolean updated = updateById(news);
        if (!updated) {
            return CommonResult.failed("更新新闻失败");
        }
        
        // 删除旧的分类关系
        LambdaQueryWrapper<NewsCategoryRel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NewsCategoryRel::getNewsId, news.getId());
        categoryRelMapper.delete(wrapper);
        
        // 保存新的分类关系
        saveNewsCategoryRels(news.getId(), categoryIds);
        
        return CommonResult.success(null);
    }

    @Override
    @Transactional
    public CommonResult deleteNews(Integer id) {
        // 删除新闻
        boolean removed = removeById(id);
        if (!removed) {
            return CommonResult.failed("删除新闻失败");
        }
        
        // 级联删除关联的分类关系会通过外键自动完成
        
        return CommonResult.success(null);
    }

    @Override
    public CommonResult getNewsDetail(Integer id) {
        // 获取新闻
        News news = getById(id);
        if (news == null) {
            return CommonResult.failed("新闻不存在");
        }
        
        // 获取分类
        List<NewsCategory> categories = getNewsCategoriesByNewsId(id);
        news.setCategories(categories);
        
        return CommonResult.success(news);
    }

    @Override
    public CommonResult updateNewsStatus(Integer id, Integer status) {
        News news = new News();
        news.setId(id);
        news.setStatus(status);
        news.setUpdateTime(LocalDateTime.now());
        
        boolean updated = updateById(news);
        if (!updated) {
            return CommonResult.failed("更新新闻状态失败");
        }
        
        return CommonResult.success(null);
    }

    @Override
    public CommonResult updateNewsTopStatus(Integer id, Integer isTop) {
        News news = new News();
        news.setId(id);
        news.setIsTop(isTop);
        news.setUpdateTime(LocalDateTime.now());
        
        boolean updated = updateById(news);
        if (!updated) {
            return CommonResult.failed("更新新闻置顶状态失败");
        }
        
        return CommonResult.success(null);
    }

    @Override
    public CommonResult getNewsList(Integer pageNum, Integer pageSize, String keyword, Integer categoryId, Integer status) {
        Page<News> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<News> wrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.hasText(keyword)) {
            wrapper.like(News::getTitle, keyword).or().like(News::getContent, keyword);
        }
        
        if (status != null) {
            wrapper.eq(News::getStatus, status);
        }
        
        // 排序
        wrapper.orderByDesc(News::getIsTop);
        wrapper.orderByDesc(News::getPublishTime);
        
        // 查询结果
        IPage<News> newsPage;
        
        // 如果有分类筛选，需要特殊处理
        if (categoryId != null && categoryId > 0) {
            // 查找属于指定分类的新闻ID列表
            LambdaQueryWrapper<NewsCategoryRel> relWrapper = new LambdaQueryWrapper<>();
            relWrapper.eq(NewsCategoryRel::getCategoryId, categoryId);
            List<NewsCategoryRel> rels = categoryRelMapper.selectList(relWrapper);
            
            if (rels.isEmpty()) {
                // 没有符合分类的新闻
                return CommonResult.success(new Page<>());
            }
            
            // 获取新闻ID列表
            List<Integer> newsIds = rels.stream()
                    .map(NewsCategoryRel::getNewsId)
                    .collect(Collectors.toList());
            
            // 添加ID条件
            wrapper.in(News::getId, newsIds);
        }
        
        // 执行查询
        newsPage = page(page, wrapper);
        
        // 填充分类信息
        for (News news : newsPage.getRecords()) {
            List<NewsCategory> categories = getNewsCategoriesByNewsId(news.getId());
            news.setCategories(categories);
        }
        
        return CommonResult.success(newsPage);
    }

    @Override
    public CommonResult getFrontNewsList(Integer pageNum, Integer pageSize, Integer categoryId) {
        Page<News> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<News> wrapper = new LambdaQueryWrapper<>();
        
        // 只查询已发布的新闻
        wrapper.eq(News::getStatus, 1);
        
        // 排序
        wrapper.orderByDesc(News::getIsTop);
        wrapper.orderByDesc(News::getPublishTime);
        
        // 查询结果
        IPage<News> newsPage;
        
        // 如果有分类筛选，需要特殊处理
        if (categoryId != null && categoryId > 0) {
            // 查找属于指定分类的新闻ID列表
            LambdaQueryWrapper<NewsCategoryRel> relWrapper = new LambdaQueryWrapper<>();
            relWrapper.eq(NewsCategoryRel::getCategoryId, categoryId);
            List<NewsCategoryRel> rels = categoryRelMapper.selectList(relWrapper);
            
            if (rels.isEmpty()) {
                // 没有符合分类的新闻
                return CommonResult.success(new Page<>());
            }
            
            // 获取新闻ID列表
            List<Integer> newsIds = rels.stream()
                    .map(NewsCategoryRel::getNewsId)
                    .collect(Collectors.toList());
            
            // 添加ID条件
            wrapper.in(News::getId, newsIds);
        }
        
        // 执行查询
        newsPage = page(page, wrapper);
        
        // 填充分类信息
        for (News news : newsPage.getRecords()) {
            List<NewsCategory> categories = getNewsCategoriesByNewsId(news.getId());
            news.setCategories(categories);
        }
        
        return CommonResult.success(newsPage);
    }

    @Override
    public CommonResult getTopNews() {
        LambdaQueryWrapper<News> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(News::getIsTop, 1);
        wrapper.eq(News::getStatus, 1);
        wrapper.orderByDesc(News::getPublishTime);
        wrapper.last("LIMIT 5"); // 最多返回5条置顶新闻
        
        List<News> topNews = list(wrapper);
        
        // 填充分类信息
        for (News news : topNews) {
            List<NewsCategory> categories = getNewsCategoriesByNewsId(news.getId());
            news.setCategories(categories);
        }
        
        return CommonResult.success(topNews);
    }

    @Override
    public void increaseViewCount(Integer id) {
        // 简单实现，不考虑并发问题
        News news = getById(id);
        if (news != null) {
            news.setViewCount(news.getViewCount() + 1);
            updateById(news);
        }
    }
    
    /**
     * 保存新闻与分类的关联关系
     */
    private void saveNewsCategoryRels(Integer newsId, List<Integer> categoryIds) {
        if (categoryIds != null && !categoryIds.isEmpty()) {
            for (Integer categoryId : categoryIds) {
                NewsCategoryRel rel = new NewsCategoryRel();
                rel.setNewsId(newsId);
                rel.setCategoryId(categoryId);
                categoryRelMapper.insert(rel);
            }
        }
    }
    
    /**
     * 根据新闻ID获取分类列表
     */
    private List<NewsCategory> getNewsCategoriesByNewsId(Integer newsId) {
        LambdaQueryWrapper<NewsCategoryRel> relWrapper = new LambdaQueryWrapper<>();
        relWrapper.eq(NewsCategoryRel::getNewsId, newsId);
        List<NewsCategoryRel> rels = categoryRelMapper.selectList(relWrapper);
        
        if (rels.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<Integer> categoryIds = rels.stream()
                .map(NewsCategoryRel::getCategoryId)
                .collect(Collectors.toList());
        
        LambdaQueryWrapper<NewsCategory> categoryWrapper = new LambdaQueryWrapper<>();
        categoryWrapper.in(NewsCategory::getId, categoryIds);
        categoryWrapper.eq(NewsCategory::getStatus, 1); // 只获取启用的分类
        
        return categoryMapper.selectList(categoryWrapper);
    }
} 